package com.httpclient;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;

import javax.net.ssl.SSLContext;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.config.SocketConfig;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

/**
 * httpclient 测试类 HttpClientTest.java
 * 
 * @author yaojinshan
 * @since 2018年5月21日下午5:23:54
 */
@SuppressWarnings({ "deprecation", "resource" })
public class HttpClientUtil{
	public static final String CHARSET_GBK = "GBK";
	static int currentNum = 0;// 计数器
	
	private static CloseableHttpClient httpsClient = null;

	static class AnyTrustStrategy implements TrustStrategy {
		public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
			return true;
		}
	}
	static {
		try {
			RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder.create();
			ConnectionSocketFactory plainSF = new PlainConnectionSocketFactory();
			registryBuilder.register("http", plainSF);

			KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
			SSLContext sslContext = SSLContexts.custom().useTLS().loadTrustMaterial(trustStore, new AnyTrustStrategy())
					.build();
			LayeredConnectionSocketFactory sslSF = new SSLConnectionSocketFactory(sslContext,
					SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

			registryBuilder.register("https", sslSF);

			Registry<ConnectionSocketFactory> registry = registryBuilder.build();

			PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(registry);
			 //连接池的相关配置
	        SocketConfig config= SocketConfig.custom().setSoTimeout(10000).
	                setSoKeepAlive(true).setTcpNoDelay(true).build();
	        connManager.setDefaultSocketConfig(config);
			connManager.setMaxTotal(500);
			httpsClient = HttpClientBuilder.create().setConnectionManager(connManager).build();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) throws Exception {
		// 1.获取该类型的最大页码数
		String body = getRequest(domain, CHARSET_GBK);
		if (null != body && !"".equals(body)) {
			Document doc = Jsoup.parse(body);
			System.out.println(doc);
		}
	}

	static String getRequest(String url, String charset){
		try {
			// 创建一个post请求
			HttpGet httpGet = new HttpGet(url);
			// 发送请求
			CloseableHttpResponse response = httpsClient.execute(httpGet);
			try {
				HttpEntity entity = response.getEntity();
				try {
					if (entity != null) {
						// 获取响应数据
						String resData = EntityUtils.toString(entity, Charset.forName(CHARSET_GBK));
						// 获取链接响应码 200请求成功 303重定向 400请求错误 401未授权 403禁止访问 404文件未找到 500服务器错误
						int responseCode = response.getStatusLine().getStatusCode();
						if (Integer.valueOf(responseCode) < 400) {
							return resData;
						}else{
							return null;
						} 
					}else{
						return null;
					}
				} finally {
					EntityUtils.consumeQuietly(entity);
				}
			} finally {
				response.close();
				httpGet.releaseConnection();
			}
		} catch (ClientProtocolException e) {
			System.out.println("request error : ---->ClientProtocolException---->" + url );
		} catch (IOException e) {
			System.out.println("request error : ---->IOException---->" + url );
		}
		return null;
	}
//	static String getRequest(String url, String charset){
//		DefaultHttpClient httpclient = new DefaultHttpClient();
//		HttpGet httpGet = new HttpGet(url);
//		// HttpGet httpGet = new HttpGet("http://www.baidu.com");
//		String body = "";
//		HttpResponse response;
//		HttpEntity entity;
//		try {
//			response = httpclient.execute(httpGet);
//			entity = response.getEntity();
//			body = EntityUtils.toString(entity, charset);// 这个就是页面源码了
//			httpGet.abort();// 中断请求,接下来可以开始另一段请求
//			// System.out.println("get: " + response.getStatusLine());// 这个可以打印状态
//			// System.out.println(body);
//			httpGet.releaseConnection();// 释放请求.如果释放了相当于要清空session
//			int responseCode = response.getStatusLine().getStatusCode();
//			if (Integer.valueOf(responseCode) < 400) {
//				return body;
//			}
//		} catch (ClientProtocolException e) {
//			System.out.println("request error : ---->ClientProtocolException---->" + url );
//		} catch (IOException e) {
//			System.out.println("request error : ---->IOException---->" + url );
//		}
//		return null;
//	}

	static void postRequest() throws Exception {
		DefaultHttpClient httpclient = new DefaultHttpClient();
		String body = "";
		HttpResponse response;
		HttpEntity entity;
		HttpPost httpPost = new HttpPost("http://www.baidu.com");// 一定要改成可以提交的地址,这里用百度代替
		List<NameValuePair> nvps = new ArrayList<NameValuePair>();
		nvps.add(new BasicNameValuePair("name", "1"));// 名值对
		nvps.add(new BasicNameValuePair("account", "xxxx"));
		httpPost.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8));
		response = httpclient.execute(httpPost);
		entity = response.getEntity();
		body = EntityUtils.toString(entity, "utf-8");
		System.out.println("Login form get: " + response.getStatusLine());// 这个可以打印状态
		httpPost.abort();
		System.out.println(body);
		httpPost.releaseConnection();
	}
	/**
	 * 下载资源方法
	 * @param resourceUrl 资源url
	 * @param resourceName 资源文件名
	 * @param targetDir 目标目录
	 */
	public static void downloadResource(String resourceUrl, String resourceName, File targetDir) {
		try {
			// 构造URL
			URL url = new URL(resourceUrl);
			// 打开连接
			URLConnection con = url.openConnection();
			con.setRequestProperty("User-Agent",
					"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36");
			// 设置请求超时为60s
			con.setConnectTimeout(30 * 1000);
			// 输入流
			InputStream is = con.getInputStream();

			// 1K的数据缓冲
			byte[] bs = new byte[2048];
			// 读取到的数据长度
			int len;
			// 输出的文件流
			File imgFile = new File(targetDir, resourceName);
			if (!imgFile.exists()) {
				imgFile.createNewFile();
			}else{
				System.out.println("downlaod repeat:" + resourceUrl);
				return;
			}
			OutputStream os = new FileOutputStream(imgFile);
			// 开始读取
			while ((len = is.read(bs)) != -1) {
				os.write(bs, 0, len);
			}
			// 完毕，关闭所有链接
			os.close();
			is.close();
			System.out.println("downlaod success:" + resourceUrl);
		} catch (MalformedURLException e) {
			System.out.println("downlaod fail:" + resourceUrl + "----> MalformedURLException");
		} catch (FileNotFoundException e) {
			System.out.println("downlaod fail:" + resourceUrl + "----> FileNotFoundException");
		} catch (IOException e) {
			System.out.println("downlaod fail:" + resourceUrl + "----> IOException");
		}
	}
	  //下载视频方法
    public static void downloadMovie(String resourceUrl, String resourceName, File targetDir){
        try {
			URL ul = new URL(resourceUrl);
			HttpURLConnection conn = (HttpURLConnection) ul.openConnection();
			conn.setConnectTimeout(60000);
			BufferedInputStream bi = new BufferedInputStream(conn.getInputStream());
			File movieFile = new File(targetDir, resourceName);
			if (!movieFile.exists()) {
				movieFile.createNewFile();
			}else{
				System.out.println("downlaod repeat:" + resourceUrl);
				return;
			}
			FileOutputStream bs = new FileOutputStream(movieFile);
			System.out.println("文件大约："+ conn.getContentLength()+ "K");
			byte[] by = new byte[2048];
			int len = 0;
			while((len=bi.read(by))!=-1){
			    bs.write(by,0,len);
			}
			bs.close();
			bi.close();
			System.out.println("downlaod success:" + resourceUrl);
		} catch (MalformedURLException e) {
			System.out.println("downlaod fail:" + resourceUrl + "----> MalformedURLException");
		} catch (FileNotFoundException e) {
			System.out.println("downlaod fail:" + resourceUrl + "----> FileNotFoundException");
		} catch (IOException e) {
			System.out.println("downlaod fail:" + resourceUrl + "----> IOException");
		}

    }
	static final String domain = "http://www.2011xx.com";
}
